#include "include/config.h"
#include "include/lib.h"
#include "include/zero.h"
#include "cxx/cxx.h"
#include "corba/corba.h"
#include "memory/memory.h"
#include "Layout.h"

using namespace zero;

extern void INITTEXT post_cpudata_init();

extern "C"
{
void relocateELF(laddr_t addr, bool isPIC)
{
	if (!isPIC)
		memcpy(reinterpret_cast<void*>(addr), reinterpret_cast<void*>(FIX_ELF_INITIAL_ADDRESS), ELF_LENGTH);
	else
		memcpy(reinterpret_cast<void*>(addr), reinterpret_cast<void*>(PIC_ELF_INITIAL_ADDRESS), ELF_LENGTH);
}

void zero_entry() __attribute__((noreturn, nothrow));
void zero_entry()
{
	zerotest::cxx_test_entry(CXXFIX_TEST_ELF_DOS_ADDR, CXXPIC_TEST_ELF_DOS_ADDR);

	zerotest::corba_test_entry(CORBAFIX_TEST_ELF_DOS_ADDR, CORBAPIC_TEST_ELF_DOS_ADDR);

// examples/ is commented <([{
	/*
	typedef Gate* (*FOO)(); FOO func;
	bool b;
	const char* s;
	Gate* g;

	relocateELF(FIX_ELF_DOS_ADDR, false);
	ABIBase::push(ABIBase::create(reinterpret_cast<unsigned char*>(FIX_ELF_INITIAL_ADDRESS), os_allocator, os_free));
	func = reinterpret_cast<FOO>(ABIBase::top()->codeEntry);
	ABIBase::top()->load();
	try {
		g = func();
		b = dynamic_cast<IFQuery*>(g)->query("def");
		s = dynamic_cast<Profile*>(g)->version();
	} catch (std::exception& e) {
		s = e.what();
		assert(s != NULL);
	}
	ABIBase::top()->unload();
	ABIBase::pop();

	relocateELF(PIC_ELF_DOS_ADDR, true);
	ABIBase::push(ABIBase::create(reinterpret_cast<unsigned char*>(PIC_ELF_INITIAL_ADDRESS), os_allocator, os_free));
	func = reinterpret_cast<FOO>(ABIBase::top()->codeEntry);
	ABIBase::top()->load();
	try {
		g = func();
		b = dynamic_cast<IFQuery*>(g)->query("abc");
		s = dynamic_cast<Profile*>(g)->version();
	} catch (std::exception& e) {
		s = e.what();
		assert(s != NULL);
	}
	ABIBase::top()->unload();
	ABIBase::pop();
	*/
// }])>

	std::abort(NULL);
}

void INITTEXT boot_c_entry() __attribute__((noreturn));
void INITTEXT boot_c_entry()
{
	post_cpudata_init();

	memory_init(MEMORY_TEMP_ADDRESS);

	cxx_init();

	zero_entry();
}
}

// vim: foldmarker=<([{,}])> foldmethod=marker
